package main

import (
	_ "embed"
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"io"
	"os"
	"path/filepath"

	"strings"
	"text/template"
)

//go:embed template\user.gohtml
var UserOrm string

type data struct {
	*File
	Ops []string
}

func gen(target io.Writer, origin string) error {
	// ast语法树解析源文件，获取ast.File
	fSet := token.NewFileSet()
	f, err := parser.ParseFile(fSet, origin, nil, parser.ParseComments)
	if err != nil {
		return err
	}

	// ast.Walk 生成期望的gen.File结构
	s := &SingleFileVisitor{}
	ast.Walk(s, f)
	file := s.Get()

	// 使用template模板
	var tpl *template.Template
	tpl, err = template.New("UserOrm").Parse(UserOrm)
	if err != nil {
		return err
	}
	// 传入目标数据执行，输出结果到target文件
	err = tpl.Execute(target, data{
		File: file,
		Ops:  []string{"Eq", "Lt", "Le", "Ge", "Gt"},
	})
	if err != nil {
		return err
	}
	return nil
}

/*
命令行跑main函数，步骤：
1. package包名改为main
2. 当前目录下执行go install . // 将当前代码生成可执行文件
3. 在user.go（源文件）所在目录下执行
	4. gen(可执行文件所在包 包名) user.go(源文件 os.Args[1])
*/

func main() {
	// 获取user_gen.go目标文件路径
	origin := os.Args[1] // user.go
	dstDir := filepath.Dir(origin)
	filename := filepath.Base(origin)
	idx := strings.LastIndex(filename, ".")
	name := filepath.Base(origin)
	dst := filepath.Join(dstDir, name[:idx]+"_gen.go")

	// 创建文件
	f, err := os.Create(dst)
	if err != nil {
		fmt.Println(err)
		return
	}
	// 生成目标文件
	err = gen(f, origin)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("generate user orm success")
}
